home *** CD-ROM | disk | FTP | other *** search
- (*----------------------------------------------------------------------*)
- (* Display_Archive_Contents --- Display contents of archive file *)
- (*----------------------------------------------------------------------*)
-
- PROCEDURE Display_Archive_Contents( ArcFileName : AnyStr );
-
- (*----------------------------------------------------------------------*)
- (* *)
- (* Procedure: Display_Archive_Contents *)
- (* *)
- (* Purpose: Displays contents of an archive (.ARC file) *)
- (* *)
- (* Calling sequence: *)
- (* *)
- (* Display_Archive_Contents( ArcFileName : AnyStr ); *)
- (* *)
- (* ArcFileName --- name of archive file whose contents *)
- (* are to be listed. *)
- (* *)
- (* Calls: *)
- (* *)
- (* Dir_Convert_Date_And_Time *)
- (* Start_Library_Listing *)
- (* End_Library_Listing *)
- (* Display_Page_Titles *)
- (* Entry_Matches *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- (*----------------------------------------------------------------------*)
- (* Map of Archive file entry header *)
- (*----------------------------------------------------------------------*)
-
- TYPE
- FNameType = ARRAY[1..13] OF CHAR;
-
- Archive_Entry_Type = RECORD
- Marker : BYTE (* Flags beginning of entry *);
- Version : BYTE (* Compression method *);
- FileName : FNameType (* file and extension *);
- Size : LONGINT (* Compressed size *);
- Date : WORD (* Packed date *);
- Time : WORD (* Packed time *);
- CRC : WORD (* Cyclic Redundancy Check *);
- OLength : LONGINT (* Original length *);
- END;
-
- CONST
- Archive_Header_Length = 29 (* Length of an archive header entry *);
- Archive_Marker = 26 (* Marks start of an archive header *);
- Max_Subdirs = 20 (* Maximum number of nested subdirs *);
-
- VAR
- ArcFile : FILE (* Archive file to be read *);
- Archive_Entry : Archive_Entry_Type (* Header for one file in archive *);
- Archive_Pos : LONGINT (* Current byte offset in archive *);
- Bytes_Read : INTEGER (* # bytes read from archive file *);
- Ierr : INTEGER (* Error flag *);
-
- (* Nested directory names in *)
- (* archive *)
-
- Subdir_Names : ARRAY[1..Max_Subdirs] OF STRING[13];
-
- Subdir_Depth : INTEGER (* Current subdirectory in archive*);
-
- Display_Entry : BOOLEAN (* TRUE to display this entry *);
- Long_Name : AnyStr (* Long file name *);
- DirS : DirStr (* Directory name *);
- FExt : ExtStr (* Extension of file name *);
-
- (*----------------------------------------------------------------------*)
- (* Get_Next_Archive_Entry --- Get next header entry in archive *)
- (*----------------------------------------------------------------------*)
-
- FUNCTION Get_Next_Archive_Entry( VAR ArcEntry : Archive_Entry_Type;
- VAR Display_Entry : BOOLEAN;
- VAR Error : INTEGER ) : BOOLEAN;
-
- (*----------------------------------------------------------------------*)
- (* *)
- (* Function: Get_Next_Archive_Entry *)
- (* *)
- (* Purpose: Gets header information for next file in archive *)
- (* *)
- (* Calling sequence: *)
- (* *)
- (* OK := Get_Next_Archive_Entry( VAR ArcEntry : *)
- (* Archive_Entry_Type; *)
- (* VAR Display_Entry : BOOLEAN; *)
- (* VAR Error : INTEGER ) : *)
- (* BOOLEAN; *)
- (* *)
- (* ArcEntry --- Header data for next file in archive *)
- (* Display_Entry --- TRUE to display this entry *)
- (* Error --- Error flag *)
- (* OK --- TRUE if header successfully found *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- BEGIN (* Get_Next_Archive_Entry *)
- (* Assume no error to start *)
- Error := 0;
- (* Assume we don't display this *)
- (* entry. *)
- Display_Entry := FALSE;
- (* Except first time, move to *)
- (* next supposed header record in *)
- (* archive. *)
-
- IF ( Archive_Pos <> 0 ) THEN
- Seek( ArcFile, Archive_Pos );
-
- (* Read in the file header entry. *)
-
- BlockRead( ArcFile, ArcEntry, Archive_Header_Length, Bytes_Read );
- Error := 0;
- (* If wrong size read, or header marker *)
- (* byte is incorrect, report archive *)
- (* format error. *)
-
- IF ( ( Bytes_Read < 2 ) OR
- ( ArcEntry.Marker <> Archive_Marker ) ) THEN
- Error := Format_Error
- ELSE (* Header looks ok -- figure out *)
- (* whaty kind of header it is. *)
- WITH ArcEntry DO
- CASE Version OF
- (* End of archive marker *)
-
- 0 : Error := End_Of_File;
-
- (* Compressed file *)
-
- 1 .. 19 : BEGIN
- (* Get position of next archive header *)
-
- IF ( Bytes_Read < Archive_Header_Length ) THEN
- Error := Format_Error
- ELSE
- BEGIN
-
- Archive_Pos := Archive_Pos + Size +
- Archive_Header_Length;
-
- (* Adjust for older archives *)
-
- IF ( Version = 1 ) THEN
- BEGIN
- OLength := Size;
- Version := 2;
- DEC( Archive_Pos , 2 );
- END;
-
- (* Display this entry *)
-
- Display_Entry := TRUE;
-
- END;
-
- END;
-
- 30 : BEGIN (* Subdirectory begins *)
-
- (* If there is room, add this *)
- (* subdirectory to current *)
- (* nesting list. *)
-
- IF ( Bytes_Read < Archive_Header_Length ) THEN
- Error := Format_Error
- ELSE IF ( Subdir_Depth < Max_Subdirs ) THEN
- BEGIN
-
- INC( Subdir_Depth );
-
- Subdir_Names[ Subdir_Depth ] :=
- COPY( FileName, 1,
- PRED( POS( #0 , FileName ) ) );
-
- END
- ELSE
- Error := Too_Many_Subs;
-
- Archive_Pos := Archive_Pos + Archive_Header_Length;
-
- END;
-
- 31 : BEGIN (* End of subdirectory *)
-
- (* Remove this subdirectory from *)
- (* current nesting *)
-
- IF ( Subdir_Depth > 0 ) THEN
- DEC( Subdir_Depth );
-
- (* Position past header *)
-
- Archive_Pos := Archive_Pos + 2;
-
- END;
-
- ELSE (* Skip over other header types *)
-
- IF ( Bytes_Read < Archive_Header_Length ) THEN
- Error := Format_Error
- ELSE
- Archive_Pos := Archive_Pos + Size +
- Archive_Header_Length;
-
- END (* CASE *);
- (* Report success/failure to calling *)
- (* routine. *)
-
- Get_Next_Archive_Entry := ( Error = 0 );
-
- END (* Get_Next_Archive_Entry *);
-
- (*----------------------------------------------------------------------*)
- (* Display_Archive_Entry --- Display archive file entry info *)
- (*----------------------------------------------------------------------*)
-
- PROCEDURE Display_Archive_Entry( Archive_Entry : Archive_Entry_Type );
-
- VAR
- I : INTEGER;
- FName : AnyStr;
- TimeDate : LONGINT;
- TimeDateW : ARRAY[1..2] OF WORD ABSOLUTE TimeDate;
-
- BEGIN (* Display_Archive_Entry *)
-
- WITH Archive_Entry DO
- BEGIN
- (* Pick up file name *)
-
- FName := COPY( FileName, 1, PRED( POS( #0 , FileName ) ) );
-
- (* See if this file matches the *)
- (* entry spec wildcard. Exit if *)
- (* not. *)
- IF Use_Entry_Spec THEN
- IF ( NOT Entry_Matches( FName ) ) THEN
- EXIT;
- (* Get date and time of creation *)
- TimeDateW[ 1 ] := Time;
- TimeDateW[ 2 ] := Date;
- (* See if we're to write out *)
- (* long file names. If so, *)
- (* get subdirectory path *)
- (* followed by file name. *)
- Long_Name := '';
-
- IF Show_Long_File_Names THEN
- IF ( Subdir_Depth > 0 ) THEN
- BEGIN
-
- FOR I := 1 TO Subdir_Depth DO
- Long_Name := Long_Name + Subdir_Names[ I ] + '\';
-
- Long_Name := Long_Name + FName;
-
- END;
- (* Display info for this entry *)
-
- Display_One_Entry( FName, Olength, TimeDate, ArcFileName,
- Current_Subdirectory, Long_Name );
-
- END;
-
- END (* Display_Archive_Entry *);
-
- (*----------------------------------------------------------------------*)
-
- BEGIN (* Display_Archive_Contents *)
-
- (* Note if LZH or LZS type. *)
-
- FSplit( ArcFileName, DirS, Long_Name, FExt );
-
- IF ( LENGTH( FExt ) > 1 ) THEN
- IF ( FExt[ 1 ] = '.' ) THEN
- DELETE( FExt, 1, 1 );
-
- (* Open archive file and initialize *)
- (* contents display. *)
-
- IF Start_Contents_Listing( ' ' + FExt + ' file: ',
- Current_Subdirectory + ArcFileName, ArcFile,
- Archive_Pos, Ierr ) THEN
- BEGIN
- (* No subdirectories yet encountered *)
- (* in archive file *)
- Subdir_Depth := 0;
- (* Loop over entries in archive file *)
-
- WHILE( Get_Next_Archive_Entry( Archive_Entry , Display_Entry , Ierr ) ) DO
- IF Display_Entry THEN
- Display_Archive_Entry( Archive_Entry );
-
- (* Close library files, complete display *)
-
- End_Contents_Listing( ArcFile , Ierr );
-
- END;
-
- END (* Display_Archive_Contents *);
-